// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: wsfuyibing <682805@qq.com>
// Date: 2025-02-11

package conf

import (
	"gitee.com/go-libs/config"
	"gitee.com/go-libs/log"
	"sync"
)

var (
	// Config
	// 配置单例如.
	Config *ErpConfig

	once = new(sync.Once)
)

// ErpConfig
// 配置.
//
// 首次加载时, 从配置文件 config/erp.yaml 文件中读取配置参数.
type ErpConfig struct {
	// Agents
	// 定义CRMEB服务映射.
	Agents map[string]*ErpAgent `yaml:"agents"`

	// Binlog
	// 定义MBS映射.
	Binlog map[string]*ErpBinlog `yaml:"binlog"`

	// Clients
	// 定义ERP系统映射.
	Clients map[string]*ErpClient `yaml:"clients"`

	Routines map[string]*ErpRoutine `json:"routines"`

	// 定义MBS服务.
	Mbs *ErpMbs `yaml:"mbs"`
}

// GetAgent
// 读取CRMEB服务.
//
// 参数 name 是数据库名, 每个数据库指向不同的CRMEB服务实例, 如下例表示数据存储在
// crmeb_pf 数据库的 CRMEB 服务实例.
//
//	conf.Config.GetAgent("crmeb_pf")
func (o *ErpConfig) GetAgent(name string) (agt *ErpAgent, has bool) {
	agt, has = o.Agents[name]
	return
}

// GetAgents
// 读取全部CRMEB服务映射.
func (o *ErpConfig) GetAgents() (mapper map[string]*ErpAgent) {
	return o.Agents
}

func (o *ErpConfig) GetRoutine(name string) (agt *ErpRoutine, has bool) {
	agt, has = o.Routines[name]
	return
}

// GetBinlog
// 读取Binlog定义.
//
// 参数 name 是数据表名，表示对哪个表的数据执行消息转发，转发后的消息可被MBS消费。
// 格式：database.table，例如 crmeb_pf.eb_store_order_status 表示将 crmeb_pf
// 数据库下 eb_store_order_status 表的数据转发到MBS。若指定的表未配置则忽略掉。
//
//	conf.Config.GetBinlog("crmeb_pf")
func (o *ErpConfig) GetBinlog(name string) (bl *ErpBinlog, has bool) {
	bl, has = o.Binlog[name]
	return
}

// GetClient
// 读取ERP服务实例.
//
//	nod.Config.GetClient("ea")
func (o *ErpConfig) GetClient(name string) (cli *ErpClient, has bool) {
	cli, has = o.Clients[name]
	return
}

// +---------------------------------------------------------------------------+
// | Internal                                                                  |
// +---------------------------------------------------------------------------+

func (o *ErpConfig) init() *ErpConfig {
	o.Agents = make(map[string]*ErpAgent)
	o.Binlog = make(map[string]*ErpBinlog)
	o.Clients = make(map[string]*ErpClient)

	if err := config.Seek("erp.yml", "erp.yaml").ScanYaml(o); err != nil {
		log.Errorf(`load erp config: error="%v"`, err)
	}

	for _, c := range o.Clients {
		c.Defaulter()
	}

	return o
}

func init() {
	once.Do(func() {
		Config = (&ErpConfig{}).init()
	})
}
